//
//  TableSource.swift
//  Demo
//
//  Created by S JZ on 2024/7/26.
//

import UIKit

public protocol TableSourceDelegate {
    func tableSource(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
    func tableSource(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView?
    func tableSource(_ tableView: UITableView, indexPath: IndexPath, cellData: (any TableCellSource)?) -> UITableViewCell?
}

public extension TableSourceDelegate {
    func tableSource(_ tableView: UITableView, indexPath: IndexPath, cellData: (any TableCellSource)?) -> UITableViewCell? { return nil }
    func tableSource(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { return nil }
    func tableSource(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { return nil }
}

public class TableSource: NSObject, UITableViewDelegate, UITableViewDataSource {
    public weak var tableView: UITableView?
    public var delegate: TableSourceDelegate?
    public var sectionArr: [SectionSource] = []
    
//    public lazy var emptyView: EmptyView = EmptyView()
    
    init(tableView: UITableView, delegate: TableSourceDelegate? = nil, sectionArr: [SectionSource] = []) {
        super.init()
        
        self.tableView = tableView
        self.delegate = delegate
        self.sectionArr = sectionArr
        
//        self.emptyView.isHidden = true
//        self.tableView?.addSubview(self.emptyView)
    }
    
    
    public func numberOfSections(in tableView: UITableView) -> Int {
        guard !sectionArr.isEmpty else { return 0 }
        return sectionArr.count
    }
    
    public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        guard let sectionData = getSectionData(section: section) else { return 0 }
        let cellDataList = sectionData.cellDataList
        return cellDataList.count
    }
    
    public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        guard let sectionData = getSectionData(section: indexPath.section) else { return UITableView.automaticDimension }
        guard let cellData = getCellData(indexPath: indexPath) else { return UITableView.automaticDimension }
        if(cellData.cellHeight > 0) { return cellData.cellHeight }
        
        return UITableView.automaticDimension
    }
    
    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // 在这里注册Cell
        guard let sectionData = getSectionData(section: indexPath.section) else { return getTableViewCell(tableView) }
        guard var cellData = getCellData(indexPath: indexPath) else { return getTableViewCell(tableView) }
        sectionData.section = indexPath.section
        cellData.indexPath = indexPath
        
        
        if let delegate, let tableViewCell = delegate.tableSource(tableView, indexPath: indexPath, cellData: cellData) {
            tableViewCell.selectionStyle = .none
            return tableViewCell
        }
        
        return getTableViewCell(tableView)
    }
    
    public func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        guard let sectionData = getSectionData(section: section) else { return 0.01 }
        if(sectionData.heardHeight > 0.01 ) { return  sectionData.heardHeight }
        return 0.01
    }
    
    public func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        guard let sectionData = getSectionData(section: section) else { return getEmptyView() }
        if(sectionData.heardHeight > 0.01) {
            if let delegate, let headView = delegate.tableSource(tableView, viewForFooterInSection: section) {
                return headView
            }
        }
        return getEmptyView()
    }
    
    public func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        guard let sectionData = getSectionData(section: section) else { return 0.01 }
        if(sectionData.footerHeight > 0.01 ) { return  sectionData.footerHeight }
        return 0.01
    }
    
    public func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        guard let sectionData = getSectionData(section: section) else { return getEmptyView() }
        if(sectionData.footerHeight > 0.01) {
            if let delegate, let headView = delegate.tableSource(tableView, viewForHeaderInSection: section) {
                return headView
            }
        }
        
        return getEmptyView()
    }
}

public extension TableSource {
    /**
     * 如果为Swift，必须将包名拼到ellClassNames中，例如：PackageName.cellClassName
     * 如果为OC，cellClassName则不加PackageName
     * Identifier 为 cellClassName
     */
    func register(cellClasss: [AnyClass]) {
        cellClasss.forEach { cls in

            tableView?.register(cls, forCellReuseIdentifier: NSStringFromClass(cls))
        }
    }
    
    /**
     * 如果为Swift，必须将包名拼到cellNibName中，例如：PackageName.cellNibName
     * 如果为OC，cellNibName则不加PackageName
     * Identifier 为 cellClassName
     */
    func register(cellNibNames: [String]) {
        cellNibNames.forEach { className in
            let pathArr = className.components(separatedBy: ".")
            var nibName = pathArr[0]
            if pathArr.count == 2 {
                nibName = pathArr[1]
            }
            if let cls = NSClassFromString(className) {
                let nib = UINib(nibName: nibName, bundle: Bundle(for: cls.self))
                tableView?.register(nib, forCellReuseIdentifier: nibName)
            }
        }
    }
}

extension TableSource {
    private func getSectionData(section: Int) -> SectionSource? {
        guard !sectionArr.isEmpty, section < sectionArr.count else { return nil }
        return sectionArr[section]
    }
    
    private func getCellData(indexPath: IndexPath) -> (any TableCellSource)? {
        guard let sectionData = getSectionData(section: indexPath.section) else { return nil }
        guard !sectionData.cellDataList.isEmpty, indexPath.row < sectionData.cellDataList.count else { return nil }
        if let cellSource = sectionData.cellDataList[indexPath.row] as? (any TableCellSource) { return cellSource }
        
        return nil
    }
    
    private func getTableViewCell(_ tableView: UITableView) -> UITableViewCell {
        var cell = tableView.dequeueReusableCell(withIdentifier: "TableSource")
        if(cell == nil) {
            cell = UITableViewCell(style: .default, reuseIdentifier: "TableSource")
            cell?.backgroundColor = .clear
            cell?.contentView.backgroundColor = .clear
        }
        
        return cell!
    }
    
    private func getEmptyView() -> UIView {
        let view = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: 0.01))
        view.backgroundColor = .clear
        return view
    }
}

